package sources;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;

/**
 * A class that contains common code used to add iCal components to the calendar.
 *
 * @author Alana Meditz
 * @author Ty Yago
 * @author Katherine Kishaba
 * @author Jimmy CUmming
 * 
 */

public class AddComponentFrame extends JFrame {
	protected static final int WIDTH = 600;
	protected static final int HEIGHT = 400;
	protected final String[] classifications = {"", "PUBLIC", "PRIVATE", "CONFIDENTIAL"};
	protected final String[] priorities = {"", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
	protected final String[] timezones = {"", "UTC-11 (Pacific/Midway)", "UTC-10 (Pacific/Hawaii)",
			"UTC-9 (America/Anchorage)", "UTC-8 (America/Los Angeles)", "UTC-7 (America/Denver)",
			"UTC-6 (America/Chicago)", "UTC-5 (America/New York)", "UTC-4 (America/Halifax)",
			"UTC-3 (America/Argentina/Buenos Aires)", "UTC-2 (America/Noronha)",
			"UTC-1 (America/Azores)", "UTC", "UTC+1 (Europe/Madrid)", "UTC+2 (Europe/Helsinki)",
			"UTC+3 (Asia/Kuwait)", "UTC+4 (Europe/Moscow)", "UTC+5 (Asia/Kabul)",
			"UTC+6 (Asia/Dhaka)", "UTC+7 (Asia/Bangkok)", "UTC+8 (Asia/Manila)",
			"UTC+9 (Asia/Tokyo)", "UTC+10 (Australia/Sydney)", "UTC+11 (Antarctica/Macquarie)",
			"UTC+12 (Pacific/Auckland)"};
	protected static int offset;
	
	protected void setUpFrame() {
		setSize(WIDTH, HEIGHT);
		setVisible(true);
	}
	
	/**
	 * Returns true if the given String follows the desired date format of "yyyymmdd-hhmmss".
	 * Returns false otherwise.
	 * 
	 * @param date The String to be tested
	 * @return True if given String follows desired date format.  False otherwise
	 */
	public boolean checkDateFormat(String date) {
		if(date.length() == 15 && date.charAt(8) == '-' && date.charAt(0) != '-'
		   && date.charAt(9) != '-') {
			try {
				Integer.parseInt(date.substring(0, 8));
				Integer.parseInt(date.substring(9, 15));
			} catch(NumberFormatException e) {
				return false;
			}
		} else {
			return false;
		}
		return true;
	}
	
	
	/**
	 * Checks format of dtstart.  If it is correct, dtstart is added to component as the DTSTART
	 * property and the method returns true.  Otherwise the method returns false and no property
	 * is added to component.
	 * 
	 * @param dtstart   String to be added to component as the DTSTART property if it is of proper
	 * 					format.
	 * @param component ICalComponent to which a DTSTART property will be added if dtstart is of
	 * 					proper format.
	 * @return			True if the format of dtstart is correct and has been added to component
	 * 						as the DTSTART property.
	 * 					False otherwise.
	 */
	public boolean addDtstart(String dtstart, ICalComponent component) {
		// Check user input
		if(dtstart.equals("")) {
			ErrorFrame errorFrame = new ErrorFrame("Start date must be provided!");
			return false;
		}
		if(!checkDateFormat(dtstart)) {
			ErrorFrame errorFrame = new ErrorFrame("Incorrect date format!");
			return false;
		}
		
		// Input passed error checking
		dtstart = dtstart + "Z";
		dtstart = dtstart.replace('-', 'T');
		component.addComponentProperty("DTSTART", dtstart);
		return true;
	}
	
	/**
	 * Checks format of dtend.  If it is correct, dtstart is added to component as the DTSTART
	 * property and the method returns true.  If it is empty, the method also returns true, but no
	 * property is added to component. Otherwise the method returns false and no property is added
	 * to component.
	 * 
	 * @param dtend		String to be added to component as the DTEND property if it is of proper
	 * 					format.
	 * @param dtstart	String that must be equal to the DTSTART property of component.
	 * @param component ICalComponent to which a DTEND property will be added if dtend is of
	 * 					proper format.
	 * @return			True if dtend is "" or if it is of proper format and has been added to
	 * 						component as the DTEND property.
	 * 					False otherwise.
	 */
	public boolean addDtend(String dtend, String dtstart, ICalComponent component) {
		// User did not enter end date
		if(dtend.equals("")) {
			return true;
		}
		
		// Check user input
		if(!checkDateFormat(dtend)) {
			ErrorFrame errorFrame = new ErrorFrame("Incorrect date format!");
			return false;
		}
		if(!isAfter(dtend, dtstart)) {
			ErrorFrame errorFrame = new ErrorFrame("End date/time must be after start date/time!");
			return false;
		}
		
		// Input passed error checking
		dtend = dtend + "Z";
		dtend = dtend.replace('-', 'T');
		component.addComponentProperty("DTEND", dtend);
		return true;
	}
	
	
	/**
	 * Returns true if the endDate String parameter represents a date after the date represented by
	 * the startDate String parameter.  Returns false otherwise.  Dates must be given in the the
	 * same time zone and in the following format: "yyyymmdd-hhmmss"
	 * 
	 * @param endDate   The String representing the end date
	 * @param startDate The String representing the start date
	 * @return          True if the first String parameter represents a date after the date represented by
	 * 						the second String parameter.
	 * 					False otherwise.
	 */
	// TODO: Try to split it up to reduce cyclomatic complexity
	public boolean isAfter(String endDate, String startDate) {
		int startYear = Integer.parseInt(startDate.substring(0, 4));
		int endYear = Integer.parseInt(endDate.substring(0, 4));
		
		if(startYear > endYear) {
			return false;
		} else if(startYear == endYear) {
			int startMonth = Integer.parseInt(startDate.substring(4, 6));
			int endMonth = Integer.parseInt(endDate.substring(4, 6));
			if(startMonth > endMonth) {
				return false;
			} else if (startMonth == endMonth) {
				int startDay = Integer.parseInt(startDate.substring(6, 8));
				int endDay = Integer.parseInt(endDate.substring(6, 8));
				if(startDay > endDay) {
					return false;
				} else if(startDay == endDay) {
					int startHour = Integer.parseInt(startDate.substring(9, 11));
					int endHour = Integer.parseInt(endDate.substring(9, 11));
					if(startHour > endHour) {
						return false;
					} else if(startHour == endHour) {
						int startMin = Integer.parseInt(startDate.substring(11, 13));
						int endMin = Integer.parseInt(endDate.substring(11, 13));
						if(startMin > endMin) {
							return false;
						} else if (startMin == endMin) {
							int startSec = Integer.parseInt(startDate.substring(13, 15));
							int endSec = Integer.parseInt(endDate.substring(13, 15));
							if(startSec >= endSec) 
								return false;
		}	}	}	}	}

		return true;
	}
	
	/**
	 * Event handler for the "Back" button
	 */
	protected class BackButtonHandler implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			setVisible(false);
		}
	}
	
	/**
	 * Converts the manualInput String parameter to the time and date offset as specified by the selected time zone
	 * (time and date are computed in relation to UTC)
	 * Returns the convertedEntry String in the following format: "yyyymmdd-hhmmss"
	 * 
	 * @param manualInput		The String representing the originally input date
	 * @return convertedEntry	The String representing the original input date in the correct time zone
	 */
	protected String convertByTimeZone(String manualInput) {
		String manualEntry = manualInput;
		String convertedEntry;
		
		String manualDate = manualEntry.substring(0, 8);
		int manualYear = Integer.parseInt(manualDate.substring(0, 4));
		int manualMonth = Integer.parseInt(manualDate.substring(4, 6));
		int manualDay = Integer.parseInt(manualDate.substring(6, 8));
		
		String manualTime = manualEntry.substring(9, 15);
		int manualHour = Integer.parseInt(manualTime.substring(0, 2));
		int manualMinute = Integer.parseInt(manualTime.substring(2, 4));
		int manualSecond = Integer.parseInt(manualTime.substring(4, 6));
		
		// System.out.println("Manually entered date and time: " + manualYear + "." + manualMonth + "." + manualDay + "." + manualHour + "." + manualMinute + "." + manualSecond);
		
		int convertedHour = 0;
		int convertedDay = 1;
		boolean dayChange = false;

		convertedHour = manualHour - (offset);
		// System.out.println(convertedHour + " = " + manualHour + " - " + offset);
		
		// System.out.println(convertedHour);

		if(convertedHour >= 24) {
			if(offset > 0) {
				convertedDay = manualDay - 1;
				dayChange = true;
			}
			else {
				convertedDay = manualDay + 1;
				dayChange = true;
			}
		}
		
		convertedHour = convertedHour % 24;
		
		if(dayChange) {
			// System.out.println("Converted date and time: " + manualYear + "." + manualMonth + "." + convertedDay + "." + convertedHour + "." + manualMinute + "." + manualSecond);
			convertedEntry = manualYear + String.format("%02d", manualMonth) + String.format("%02d", convertedDay) + "-" + String.format("%02d", convertedHour) + String.format("%02d", manualMinute) + String.format("%02d", manualSecond);
		}
		else {
			// System.out.println("Converted date and time: " + manualYear + "." + manualMonth + "." + manualDay + "." + convertedHour + "." + manualMinute + "." + manualSecond);
			convertedEntry = manualYear + String.format("%02d", manualMonth) + String.format("%02d", manualDay) + "-" + String.format("%02d", convertedHour) + String.format("%02d", manualMinute) + String.format("%02d", manualSecond);
		}
		
		return convertedEntry;
	}
}